package com.iretailer.report.quartz.systemTask;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.model.Categories;
import com.iretailer.report.model.Location;
import com.iretailer.report.model.WeatherCode;
import com.iretailer.report.model.Weathers;
import com.iretailer.report.quartz.model.BaiduResult;
import com.iretailer.report.quartz.model.BaiduWeather;
import com.iretailer.report.quartz.model.BaiduWeatherData;
import com.iretailer.report.quartz.model.QuartTask;
import com.iretailer.report.service.CategoriesService;
import com.iretailer.report.service.LocationService;
import com.iretailer.report.service.QuartTaskService;
import com.iretailer.report.service.WeatherService;
import com.iretailer.report.util.GetId;
import com.iretailer.report.util.StringUtil;
import com.iretailer.report.util.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Auther Bennie
 * @Date 2020/6/9 16:11
 * @Description
 */
@Component
public class WeatherTask {


    private Logger log = LoggerFactory.getLogger(WeatherTask.class);
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private QuartTaskService quartTaskService;
    @Autowired
    private WeatherService weatherService;
    @Autowired
    private LocationService locationService;
    @Autowired
    private CategoriesService categoriesService;

    private static String hefengIcon = "https://cdn.heweather.com/cond_icon/{0}.png";

    public void execute() {
        log.error(" ==== execute WeatherTask ====");

        QuartTask task = quartTaskService.getOne(new QueryWrapper<QuartTask>().lambda().eq(QuartTask::getSpringId, "weatherTask").eq(QuartTask::getJobName, "weatherTask"));
//        String otherMessage = task.getOtherMessage();
//        Map omMap = JSON.parseObject(otherMessage, Map.class);
        List<Categories> apiTypes = categoriesService.findChildrenCategoriesByKeyName("WeatherApiType");
        Map<String, Categories> apiTypeMaps = apiTypes.stream().collect(Collectors.toMap(Categories::getId, a -> a));
        try {
            List<Location> allLocations = locationService.list(new QueryWrapper<Location>().lambda().eq(Location::getGetWeather, 1).orderByAsc(Location::getRanked));
            List<Weathers> weathers = new ArrayList<>();
            allLocations.forEach(it -> {
                if (it.getGetWeather() > 0) {
                    String apiType = ""; // 不能为 null
                    String apiKey = null;
                    if (it.getApiTypeId() != null) {
                        Categories categories = apiTypeMaps.get(it.getApiTypeId());
                        apiKey = categories.getData();
                        apiType = categories.getKeyName().toLowerCase();
                    }
                    // 默认走和风
                    weathers.addAll(getHefengWeather(it, apiKey));
                }
            });
            if (weathers.size() > 0) {
                weatherService.replaceWeather(weathers);
            }
            log.error(" === over WeatherTask");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }


    public List<Weathers> getHefengWeather(Location location, String api_ak) {
        String ak = "d6a177a1fb504906a3a8b86500ae6c66";
        if (StringUtil.notEmpty(api_ak)) {
            ak = api_ak;
        }
        String unit = "m";
        if (StringUtil.notEmpty(location.getUnit())) {
            unit = location.getUnit();
        }
        String language = "en";
//        if (StringUtil.notEmpty(location.getWeatherLanguage())) {
//            String weatherLanguage = location.getWeatherLanguage();
//            if (weatherLanguage.equals("zh-cn") || weatherLanguage.equals("en") || weatherLanguage.equals("ja")) {
//                language = "en";
//            } else {
//                language = weatherLanguage;
//            }
//        }

        String template = "https://api.heweather.net/s6/weather?unit={0}&key={1}&lang={2}&location={3}";
        String url = MessageFormat.format(template, unit, ak, language, location.getWeatherCode());
        String responeStr = restTemplate.getForObject(url, String.class);
//        log.error(responeStr);
        JSONObject heFengResult = JSON.parseObject(responeStr);
        JSONArray weathers = heFengResult.getJSONArray("HeWeather6");
        if (weathers.size() > 0) {
            JSONObject weatherResult = weathers.getJSONObject(0);
            String status = weatherResult.getString("status");
            if (status.equals("ok")) {
                JSONArray ws = weatherResult.getJSONArray("daily_forecast");
                List<Weathers> replaceWeather = new ArrayList<>();
                for (int i = 0, len = ws.size(); i < len; i++) {
                    JSONObject find = ws.getJSONObject(i);
                    Weathers weather = new Weathers();
                    weather.setId(GetId.UUID());
                    weather.setDate(TimeUtil.parse_LocalDate(find.getString("date")));
                    weather.setCityId(location.getId());
                    weather.setCityName(location.getName());
//                    String wn = find.getString("cond_txt_d") + "/" + find.getString("cond_txt_n");
                    String wn = WeatherCode.getByCode(find.getInteger("cond_code_d")).getEn();
                    weather.setWeatherName(wn);
                    weather.setWindDir(find.getString("wind_dir"));
                    weather.setWindDeg(find.getInteger("wind_deg"));
                    weather.setWindSc(find.getString("wind_sc"));
                    weather.setWindSpd(find.getInteger("wind_spd"));
                    weather.setHighTemp(find.getDouble("tmp_max"));
                    weather.setLowTemp(find.getDouble("tmp_min"));
                    switch (unit) {
                        case "i":
                            weather.setTempUnit("℉");
                            break;
                        default:
                            weather.setTempUnit("℃");
                            break;
                    }
                    // PM25
                    weather.setPm25(0.0);
                    weather.setDayPictureUrl(MessageFormat.format(hefengIcon, find.getString("cond_code_d")));
                    weather.setNightPictureUrl(MessageFormat.format(hefengIcon, find.getString("cond_code_n")));
                    replaceWeather.add(weather);
                }
                return replaceWeather;
            } else {
                log.error("HeFeng weather Error status:{}", status);
            }
        }
        return Collections.emptyList();
    }

    /**
     * 由于天气图标，百度天气废弃
     *
     * @param location
     * @param api_ak
     * @return
     */
    @Deprecated
    public List<Weathers> getBaiduWeather(Location location, String api_ak) {

        String ak = "1cU6UvzVVGCfYbeDMua8XEzP";
        if (StringUtil.notEmpty(api_ak)) {
            ak = api_ak;
        }
        String url = MessageFormat.format("http://api.map.baidu.com/telematics/v3/weather?location={0}&output=json&ak={1}", location.getName(), ak);
        String responeStr = restTemplate.getForObject(url, String.class);
//        log.error(responeStr);
        BaiduWeather baiduWeather = JSON.parseObject(responeStr, BaiduWeather.class);
        if (baiduWeather.getStatus().equals("success")) {
            BaiduResult baiduResult = baiduWeather.getResults().get(0);
//            val baiduWeatherData = baiduResult.weather_data!!.get(0)
            List<Weathers> replaceWeather = new ArrayList<>();
            for (int i = 0, len = baiduResult.getWeather_data().size(); i < len; i++) {
                Weathers weather = new Weathers();
                weather.setId(GetId.UUID());
                if (i == 0) {
                    weather.setDate(baiduWeather.getDate());
                } else {
                    weather.setDate(baiduWeather.getDate().plusDays(i));
                }
                weather.setCityId(location.getId());
                weather.setCityName(location.getName());
                BaiduWeatherData bwd = baiduResult.getWeather_data().get(i);
                String temperatue = bwd.getTemperature();
                temperatue = temperatue.replace(" ", "");
                temperatue = temperatue.replace("℃", "");
                if (temperatue.contains("~")) {
                    String[] temps = temperatue.split("~");
                    weather.setHighTemp(Double.valueOf(temps[0]));
                    weather.setLowTemp(Double.valueOf(temps[1]));
                } else {
                    weather.setHighTemp(Double.valueOf(temperatue));
                    weather.setLowTemp(Double.valueOf(temperatue));
                }
                weather.setWeatherName(bwd.getWeather());
                weather.setWind(bwd.getWind());
                // PM25
                weather.setPm25(baiduResult.getPm25());
                weather.setTempUnit("℃");
                weather.setDayPictureUrl(bwd.getDayPictureUrl());
                weather.setNightPictureUrl(bwd.getNightPictureUrl());
                replaceWeather.add(weather);
            }
//            weatherService.replaceWeather(replaceWeather);
//            result = true;
            return replaceWeather;
        } else {
            log.error("Weather Acquisition Error cityId:{} cityName:{} msg:{}", location.getId(), location.getName(), responeStr);
        }
        return Collections.emptyList();
    }

    @Deprecated
    private List<Weathers> getWeather(String apiType, String apiKey, Location location) {
        List<Weathers> weathers = new ArrayList<>();
        switch (apiType) {
            case "Baidu":
                if (StringUtil.notEmpty(location.getName())) {
                    weathers.addAll(getBaiduWeather(location, apiKey));
                }
                break;
            default:
                if (StringUtil.notEmpty(location.getWeatherCode())) {
                    weathers.addAll(getHefengWeather(location, apiKey));
                } else {
                    if (StringUtil.notEmpty(location.getName())) {
                        weathers.addAll(getBaiduWeather(location, null));
                    }
                }
                break;
        }

        return weathers;
    }

}
